package com.example.shuiyin.controller;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.example.shuiyin.dto.ApiResponse;
import com.example.shuiyin.dto.ParseRequest;
import com.example.shuiyin.dto.ProcessRecordDto;
import com.example.shuiyin.entity.User;
import com.example.shuiyin.exception.AppException;
import com.example.shuiyin.exception.ErrorCode;
import com.example.shuiyin.service.AuthService;
import com.example.shuiyin.service.MediaService;
import com.example.shuiyin.entity.ProcessRecord;
import com.example.shuiyin.service.ProcessRecordService;
import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.core.io.FileSystemResource;
import org.springframework.core.io.Resource;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.stream.Collectors;

@RestController
@RequestMapping("/api/media")
@RequiredArgsConstructor
@Slf4j
public class MediaController {

    private final MediaService mediaService;
    private final AuthService authService;
    private final ProcessRecordService processRecordService;

    /**
     * 解析媒体链接
     */
    @PostMapping("/parse")
    public ResponseEntity<ApiResponse<ProcessRecordDto>> parseUrl(@RequestBody ParseRequest request,
                                                   @RequestAttribute("userId") Long userId) {
        try {
            ProcessRecord record = mediaService.parseMediaUrl(request.getUrl(), userId);
            return ResponseEntity.ok(ApiResponse.success("解析链接成功", ProcessRecordDto.fromEntity(record)));
        } catch (Exception e) {
            log.error("解析链接失败: {}", e.getMessage(), e);
            throw new AppException("解析链接失败: " + e.getMessage(), ErrorCode.INVALID_PARAMETER);
        }
    }

    /**
     * 上传文件处理
     */
    @PostMapping("/upload")
    public ResponseEntity<ApiResponse<List<ProcessRecordDto>>> uploadFiles(
            @RequestParam("files") List<MultipartFile> files,
            @RequestAttribute("userId") Long userId) {
        try {
            List<ProcessRecord> records = mediaService.processUploadedFiles(files, userId);
            
            List<ProcessRecordDto> dtos = records.stream()
                    .map(ProcessRecordDto::fromEntity)
                    .collect(Collectors.toList());
                    
            return ResponseEntity.ok(ApiResponse.success("文件上传成功", dtos));
        } catch (IOException e) {
            log.error("上传文件失败: {}", e.getMessage(), e);
            throw new AppException("上传文件失败: " + e.getMessage(), ErrorCode.FILE_UPLOAD_ERROR);
        }
    }

    /**
     * 获取处理记录列表
     */
    @GetMapping("/records")
    public ResponseEntity<ApiResponse<Page<ProcessRecordDto>>> getRecords(
            @RequestParam(defaultValue = "1") int page,
            @RequestParam(defaultValue = "10") int size,
            @RequestAttribute("userId") Long userId) {
        
        Page<ProcessRecord> records = processRecordService.findPageByUserId(userId, page, size);
        
        // 转换为DTO
        Page<ProcessRecordDto> dtoPage = new Page<>(records.getCurrent(), records.getSize(), records.getTotal());
        
        List<ProcessRecordDto> dtos = records.getRecords().stream()
                .map(ProcessRecordDto::fromEntity)
                .collect(Collectors.toList());
                
        dtoPage.setRecords(dtos);
        
        return ResponseEntity.ok(ApiResponse.success("获取处理记录成功", dtoPage));
    }

    /**
     * 获取处理记录详情
     */
    @GetMapping("/record/{id}")
    public ResponseEntity<ApiResponse<ProcessRecordDto>> getRecord(
            @PathVariable Long id,
            @RequestAttribute("userId") Long userId) {
        
        ProcessRecord record = processRecordService.findById(id);
        
        if (record == null) {
            throw new AppException("记录不存在", ErrorCode.RESOURCE_NOT_FOUND);
        }
        
        // 验证用户是否有权限访问该记录
        if (!record.getUserId().equals(userId)) {
            throw new AppException("无权访问该记录", ErrorCode.FORBIDDEN);
        }
        
        return ResponseEntity.ok(ApiResponse.success("获取处理记录成功", ProcessRecordDto.fromEntity(record)));
    }

    /**
     * 获取处理后的文件
     */
    @GetMapping("/file/{filename:.+}")
    public ResponseEntity<?> getFile(
            @PathVariable String filename,
            @RequestAttribute(value = "userId", required = false) Long userId) {
        log.info("获取文件: {}", filename);
        
        // 权限验证：检查文件归属权
        if (userId != null) {
            boolean hasAccess = processRecordService.checkFileAccess(filename, userId);
            if (!hasAccess) {
                return ResponseEntity.status(HttpStatus.FORBIDDEN)
                    .body(ApiResponse.error("无权访问此文件"));
            }
        } else {
            // 如果是公开访问，检查文件是否允许公开访问
            boolean isPublic = processRecordService.isFilePublicAccessible(filename);
            if (!isPublic) {
                return ResponseEntity.status(HttpStatus.UNAUTHORIZED)
                    .body(ApiResponse.error("需要登录才能访问此文件"));
            }
        }
        
        String filePath = Paths.get(System.getProperty("file.result.path"), filename).toString();
        Resource resource = new FileSystemResource(filePath);
        
        if (!resource.exists()) {
            return ResponseEntity.status(HttpStatus.NOT_FOUND)
                .body(ApiResponse.error("文件不存在"));
        }
        
        String contentType;
        if (filename.endsWith(".mp4")) {
            contentType = "video/mp4";
        } else if (filename.endsWith(".jpg") || filename.endsWith(".jpeg")) {
            contentType = "image/jpeg";
        } else if (filename.endsWith(".png")) {
            contentType = "image/png";
        } else {
            contentType = "application/octet-stream";
        }
        
        return ResponseEntity.ok()
                .contentType(MediaType.parseMediaType(contentType))
                .header(HttpHeaders.CONTENT_DISPOSITION, "inline; filename=\"" + resource.getFilename() + "\"")
                .body(resource);
    }

    /**
     * 根据token解析媒体链接
     */
    @PostMapping("/parse/token")
    public ResponseEntity<ApiResponse<ProcessRecordDto>> parseUrlByToken(
            @RequestBody Map<String, String> request) {
        try {
            String token = request.get("token");
            String url = request.get("url");
            
            if (token == null || token.trim().isEmpty()) {
                return ResponseEntity.badRequest()
                        .body(ApiResponse.error("Token不能为空"));
            }
            
            if (url == null || url.trim().isEmpty()) {
                return ResponseEntity.badRequest()
                        .body(ApiResponse.error("URL不能为空"));
            }
            
            // 验证token并获取用户ID
            if (!authService.validateUserToken(token)) {
                return ResponseEntity.status(HttpStatus.UNAUTHORIZED)
                        .body(ApiResponse.error("无效的token"));
            }
            
            String userIdStr = authService.getTokenProvider().getUserIdFromToken(token);
            Long userId = Long.valueOf(userIdStr);
            
            ProcessRecord record = mediaService.parseMediaUrl(url, userId);
            return ResponseEntity.ok(ApiResponse.success("解析链接成功", ProcessRecordDto.fromEntity(record)));
        } catch (AppException e) {
            log.error("解析链接失败: {}", e.getMessage());
            return ResponseEntity.status(e.getErrorCode().getCode())
                    .body(ApiResponse.error(e.getMessage()));
        } catch (Exception e) {
            log.error("解析链接失败: {}", e.getMessage(), e);
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
                    .body(ApiResponse.error("解析链接失败: " + e.getMessage()));
        }
    }
    
    /**
     * 根据token获取处理记录列表
     */
    @PostMapping("/records/token")
    public ResponseEntity<ApiResponse<Page<ProcessRecordDto>>> getRecordsByToken(
            @RequestBody Map<String, String> request) {
        try {
            String token = request.get("token");
            String pageStr = request.get("page");
            String sizeStr = request.get("size");
            
            if (token == null || token.trim().isEmpty()) {
                return ResponseEntity.badRequest()
                        .body(ApiResponse.error("Token不能为空"));
            }
            
            // 验证token并获取用户ID
            if (!authService.validateUserToken(token)) {
                return ResponseEntity.status(HttpStatus.UNAUTHORIZED)
                        .body(ApiResponse.error("无效的token"));
            }
            
            String userIdStr = authService.getTokenProvider().getUserIdFromToken(token);
            Long userId = Long.valueOf(userIdStr);
            
            int page = 1;
            int size = 10;
            
            if (pageStr != null && !pageStr.trim().isEmpty()) {
                try {
                    page = Integer.parseInt(pageStr);
                } catch (NumberFormatException e) {
                    // 使用默认值
                }
            }
            
            if (sizeStr != null && !sizeStr.trim().isEmpty()) {
                try {
                    size = Integer.parseInt(sizeStr);
                } catch (NumberFormatException e) {
                    // 使用默认值
                }
            }
            
            Page<ProcessRecord> records = processRecordService.findPageByUserId(userId, page, size);
            
            // 转换为DTO
            Page<ProcessRecordDto> dtoPage = new Page<>(records.getCurrent(), records.getSize(), records.getTotal());
            
            List<ProcessRecordDto> dtos = records.getRecords().stream()
                    .map(ProcessRecordDto::fromEntity)
                    .collect(Collectors.toList());
                    
            dtoPage.setRecords(dtos);
            
            return ResponseEntity.ok(ApiResponse.success("获取处理记录成功", dtoPage));
        } catch (AppException e) {
            log.error("获取处理记录失败: {}", e.getMessage());
            return ResponseEntity.status(e.getErrorCode().getCode())
                    .body(ApiResponse.error(e.getMessage()));
        } catch (Exception e) {
            log.error("获取处理记录失败: {}", e.getMessage(), e);
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
                    .body(ApiResponse.error("获取处理记录失败: " + e.getMessage()));
        }
    }
    
    /**
     * 根据token获取处理记录详情
     */
    @PostMapping("/record/token")
    public ResponseEntity<ApiResponse<ProcessRecordDto>> getRecordByToken(
            @RequestBody Map<String, String> request) {
        try {
            String token = request.get("token");
            String recordId = request.get("recordId");
            
            if (token == null || token.trim().isEmpty()) {
                return ResponseEntity.badRequest()
                        .body(ApiResponse.error("Token不能为空"));
            }
            
            if (recordId == null || recordId.trim().isEmpty()) {
                return ResponseEntity.badRequest()
                        .body(ApiResponse.error("记录ID不能为空"));
            }
            
            // 验证token并获取用户ID
            if (!authService.validateUserToken(token)) {
                return ResponseEntity.status(HttpStatus.UNAUTHORIZED)
                        .body(ApiResponse.error("无效的token"));
            }
            
            String userIdStr = authService.getTokenProvider().getUserIdFromToken(token);
            Long userId = Long.valueOf(userIdStr);
            
            ProcessRecord record = processRecordService.findById(Long.valueOf(recordId));
            
            if (record == null) {
                return ResponseEntity.status(HttpStatus.NOT_FOUND)
                        .body(ApiResponse.error("记录不存在"));
            }
            
            // 验证用户是否有权限访问该记录
            if (!record.getUserId().equals(userId)) {
                return ResponseEntity.status(HttpStatus.FORBIDDEN)
                        .body(ApiResponse.error("无权访问该记录"));
            }
            
            return ResponseEntity.ok(ApiResponse.success("获取处理记录成功", ProcessRecordDto.fromEntity(record)));
        } catch (AppException e) {
            log.error("获取处理记录详情失败: {}", e.getMessage());
            return ResponseEntity.status(e.getErrorCode().getCode())
                    .body(ApiResponse.error(e.getMessage()));
        } catch (Exception e) {
            log.error("获取处理记录详情失败: {}", e.getMessage(), e);
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
                    .body(ApiResponse.error("获取处理记录详情失败: " + e.getMessage()));
        }
    }
    
    /**
     * 根据token获取处理后的文件
     */
    @PostMapping("/file/token")
    public ResponseEntity<?> getFileByToken(
            @RequestBody Map<String, String> request) {
        try {
            String token = request.get("token");
            String filename = request.get("filename");
            
            if (token == null || token.trim().isEmpty()) {
                return ResponseEntity.badRequest()
                        .body(ApiResponse.error("Token不能为空"));
            }
            
            if (filename == null || filename.trim().isEmpty()) {
                return ResponseEntity.badRequest()
                        .body(ApiResponse.error("文件名不能为空"));
            }
            
            // 验证token并获取用户ID
            if (!authService.validateUserToken(token)) {
                return ResponseEntity.status(HttpStatus.UNAUTHORIZED)
                        .body(ApiResponse.error("无效的token"));
            }
            
            String userIdStr = authService.getTokenProvider().getUserIdFromToken(token);
            Long userId = Long.valueOf(userIdStr);
            
            log.info("用户[{}]通过token下载文件: {}", userId, filename);
            
            // TODO: 根据文件名和用户ID验证权限
            
            String filePath = Paths.get(System.getProperty("file.result.path"), filename).toString();
            Resource resource = new FileSystemResource(filePath);
            
            if (!resource.exists()) {
                return ResponseEntity.status(HttpStatus.NOT_FOUND)
                    .body(ApiResponse.error("文件不存在"));
            }
            
            String contentType;
            if (filename.endsWith(".mp4")) {
                contentType = "video/mp4";
            } else if (filename.endsWith(".jpg") || filename.endsWith(".jpeg")) {
                contentType = "image/jpeg";
            } else if (filename.endsWith(".png")) {
                contentType = "image/png";
            } else {
                contentType = "application/octet-stream";
            }
            
            return ResponseEntity.ok()
                    .contentType(MediaType.parseMediaType(contentType))
                    .header(HttpHeaders.CONTENT_DISPOSITION, "inline; filename=\"" + resource.getFilename() + "\"")
                    .body(resource);
        } catch (Exception e) {
            log.error("获取文件失败: {}", e.getMessage(), e);
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
                    .body(ApiResponse.error("获取文件失败: " + e.getMessage()));
        }
    }
} 